package net.kingborn.common.command;

import com.alibaba.fastjson.JSONObject;
import net.kingborn.common.entry.Result;
import net.kingborn.common.exception.BizException;
import net.kingborn.common.util.JsonKit;
import net.kingborn.common.util.StrKit;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Field;


public abstract class BaseCommand {

    private Result result;
    protected JSONObject data;
    private JSONObject paramObj;

    public BaseCommand() {
        this.result = new Result();
        this.data = new JSONObject();
    }

    public Result doAction(JSONObject paramObj) throws Exception {
        this.paramObj = paramObj;

        initArgs();

        try {
            init();
            doCommand();

        } finally {
            doFinally();
        }

        result.setData(JSONObject.parseObject(JsonKit.toJson(data)));

        return result;
    }

    private void initArgs() throws IllegalAccessException {
        Field[] fields = this.getClass().getDeclaredFields();

        Param param = null;
        for (Field field : fields) {
            param = field.getAnnotation(Param.class);
            if (param != null) {
                // 对变量进行赋值
                handleField(field, param);
            }

        }
    }

    private void handleField(Field field, Param param) throws IllegalAccessException {
        field.setAccessible(true);

        String paramName = StrKit.notBlank(param.name()) ? param.name() : param.value();
        paramName = StrKit.notBlank(paramName) ? paramName : field.getName();

        Object paramValue = null;
        try {
            paramValue = paramObj.getObject(paramName, field.getType());

            // 考虑登录拦截器
            if (paramValue == null && "currentUser".equals(paramName)) {
                ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
                HttpServletRequest request = attributes.getRequest();
                paramValue = request.getAttribute("currentUser");
            }

        } catch (Exception e) {
            if (StrKit.notBlank(param.defaultValue())) {
                field.set(this, JSONObject.parseObject(param.defaultValue(), field.getType()));
            }
            return;
        }

        if (paramValue == null && !param.required()) {
            if (StrKit.notBlank(param.defaultValue())) {
                field.set(this, JSONObject.parseObject(param.defaultValue(), field.getType()));
            }

            return;
        }

        if (paramValue == null && param.required()) {
            throw new BizException("参数【" + paramName + "】不能为空！");
        }

        field.set(this, paramValue);
    }

    /**
     * 初始化参数
     *
     * @throws Exception
     */
    protected abstract void init() throws Exception;

    /**
     * 处理业务
     *
     * @throws Exception
     */
    protected abstract void doCommand() throws Exception;

    /**
     * 做收尾工作
     *
     * @throws Exception
     */
    protected void doFinally() throws Exception {}

}
